package com.fuhao.pay.callback.template;

import com.fuhao.pay.asyntask.PayLogAsynTask;
import com.fuhao.pay.constant.PayConstant;
import com.fuhao.pay.entity.PaymentTransactionLogEntity;
import com.fuhao.pay.mapper.PaymentTransactionLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 聚合支付异步回调模板
 */
@Slf4j
@Component
public abstract class AbstractPayCallbackTemplate {

	@Autowired
	private PayLogAsynTask payLogAsynTask;

	/**
	 * 获取所有请求的参数，封装成Map集合 并且验证是否被篡改
	 * 
	 * @param req
	 * @param resp
	 * @return
	 */
	public abstract Map<String, String> verifySignature(HttpServletRequest req, HttpServletResponse resp,Map<String, String> params);

	/**
	 * 异步回调执行业务逻辑
	 *
	 * @param verifySignature
	 */
	public abstract String asyncService(Map<String, String> verifySignature) throws Exception;

	/**
     * 失败结果
	 * @return
     */
	public abstract String failResult() throws Exception;

	/**
     * 成功结果
	 * @return
     */
	public abstract String successResult() throws Exception;

	/**
	 * *1. 将报文数据存放到es <br>
	 * 1. 验证报文参数<br>
	 * 2. 将日志根据支付id存放到数据库中<br>
	 * 3. 执行的异步回调业务逻辑<br>
	 */
	public String asyncCallBack(HttpServletRequest req, HttpServletResponse resp, Map<String, String> params) throws Exception {
		// 1. 验证报文参数 相同点 获取所有的请求参数封装成为map集合 并且进行参数验证
		Map<String, String> verifySignature = verifySignature(req, resp,params);
		// 2.将日志根据支付id存放到数据库中
		String paymentId = verifySignature.get("paymentId");
		if (StringUtils.isEmpty(paymentId)) {
			return failResult();
		}

		// 3.采用异步形式写入日志到数据库中
		log.info(">>>>>asyncCallBack service 01");
		payLogAsynTask.payLog(paymentId,verifySignature);
		log.info(">>>>>asyncCallBack service 04");

		// 3.采用异步形式写入日志到数据库中
		//ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
		//threadPoolTaskExecutor.execute(new PayLogThread(paymentId, verifySignature));
		String result = verifySignature.get(PayConstant.RESULT_NAME);
		// 4.201报文验证签名失败
		if (result.equals(PayConstant.RESULT_PAYCODE_201)) {
			return failResult();
		}
		// 5.执行的异步回调业务逻辑
		return asyncService(verifySignature);
	}

}
